package job

import (
	"fmt"
	"gcrontab/common"
	"math/rand"
	"os/exec"
	"time"
)

type Executor struct{}

var G_executor *Executor

//执行任务
//防止分布式环境下并发执行
func (e *Executor) ExecuteJob(info *common.JobExecuteInfo) {
	go func() {
		result := &common.JobExecuteResult{
			ExecuteInfo: info,
		}

		//随机睡0-500毫秒，让抢锁更均匀
		time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
		//获取分布式锁
		jobLock := G_jobMgr.CreateJobLock(info.Job.Name)
		startTime := time.Now()

		//上锁
		err := jobLock.TryLock()

		//结束时释放锁
		defer jobLock.UnLock()

		if err != nil { //上锁失败
			result.Output = make([]byte, 0)
			result.Err = err
			result.StartTime = startTime
			result.EndTime = time.Now()
			fmt.Println("上锁失败", string(result.Output), result.Err)
		} else { //上锁成功
			//重置启动时间
			result.StartTime = time.Now()
			//执行shell命令
			cmd := exec.CommandContext(info.CancelCtx, common.BIN_BASH_COMMAND, "-c", info.Job.Command)
			outPut, err := cmd.CombinedOutput()

			result.Output = outPut
			result.Err = err
			result.EndTime = time.Now()
			fmt.Println("上锁成功", string(result.Output), result.Err)
			//任务执行完成后，把执行结果返回给调度器
			//调度器从executingTable中移除执行项
			G_scheduler.PushJobResult(result)  //ps:上锁失败不发送给调度器
		}
	}()
}

//初始化任务执行器
func InitExecutor() (err error) {
	G_executor = &Executor{}
	return
}
